//
//  OPForum.m
//  OPFramework
//
//  Created by malcom on 7/12/08.
//  Copyright 2008 __MyCompanyName__. All rights reserved.
//

#import "OPForum.h"
#import "OPBoard.h"
#import "OPTopic.h"

@implementation OPForum

@synthesize _forumID;
@synthesize _forumPages;
@synthesize _childs;
@synthesize _forumPassword;
@synthesize p_forumName;
@synthesize p_lastPostDate;
@synthesize p_forumType;
@synthesize p_parentForum;
@synthesize p_postsNumber;
@synthesize p_topicsNumber;
@synthesize p_forumIcon;
@synthesize p_lastPoster;
@synthesize p_lastPostSubject;
@synthesize p_lastPostID;
@synthesize p_newTopicsSinceLogin;	
@synthesize p_updatedTopicsSinceLogin;	

- (id) initWithForumID:(int) _idforum ofBoard:(OPBoard *) _board {
	self = [super initWithBoard: _board];
	if (self != nil) {
		_forumID = _idforum;
		_forumPages = [[OPPageContainer alloc] init];
		_childs = [[NSMutableArray alloc] init];
		_forumPassword = [[NSString alloc] init];
	}
	return self;
}

- (NSString *) description {
	return [NSString stringWithFormat: @"OPForum: '%@' (id: %d) with %d pages (%d cached) with %d topics",
						p_forumName,_forumID,_forumPages.p_totalElements,[_forumPages.p_pagesContainer count],[_forumPages realElements]];
}

- (id) initByLoadingPropertiesDictionary:(NSDictionary *) _dict fromBoard:(OPBoard *) _board {
	self = [super initWithBoard: _board];
	if (self != nil) {		
		
		_forumID = [[_dict objectForKey:_OPForum_ForumID] intValue];
		_forumPages = [[OPPageContainer alloc] init];
		_childs = [[NSMutableArray alloc] init];
		_forumPassword = [[NSString alloc] init];
		
		// load properties
		[self _loadForumProperties: _dict];
	}
	return self;
}

		
- (void) _loadForumProperties:(NSDictionary *) _dic {

	// forum icon image
	[p_forumIcon release]; p_forumIcon = nil;
	NSString *fpath = [NSString stringWithFormat: @"%@/%@",_delegateBoard.obj_boardRootPath,[_dic objectForKey: _OPForum_ForumImage]];
	//p_forumIcon = [[NSImage alloc] initWithContentsOfURL: [NSURL URLWithString: fpath]];
	p_forumIcon = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: fpath]];
	
	// forum name
	[p_forumName release]; p_forumName = nil;
	p_forumName = [[NSString alloc] initWithString: [_dic objectForKey: _OPForum_ForumName]];
	
	// last post subject
	[p_lastPostSubject release]; p_lastPostSubject = nil;
	p_lastPostSubject = [[NSString alloc] initWithString: [_dic objectForKey: _OPForum_LastPostSubject]];

	// last post date
	[p_lastPostDate release]; p_lastPostDate = nil;
	p_lastPostDate = [[NSDate dateWithTimeIntervalSince1970: [[_dic objectForKey:_OPForum_LastPostTime] longLongValue]] retain];
	
	// number of posts
	[p_postsNumber release]; p_postsNumber = nil;
	p_postsNumber = [[NSNumber alloc] initWithInt: [[_dic objectForKey: _OPForum_NumberOfPosts] intValue]];

	// number of topics
	[p_topicsNumber release]; p_topicsNumber = nil;
	p_topicsNumber = [[NSNumber alloc] initWithInt: [[_dic objectForKey: _OPForum_NumberOfTopics] intValue]];
	
	// forum type
	[p_forumType release]; p_forumType = nil;
	p_forumType = [[NSNumber alloc] initWithInt: [[_dic objectForKey: _OPForum_ForumType] intValue]];

	// parent forum
	[p_parentForum release];
	p_parentForum = [[_delegateBoard.obj_boardStructure getForumFromID: [_dic objectForKey: _OPForum_ParentForumID]] retain];
	
	// last poster
	p_lastPoster = [[_delegateBoard.obj_membersCache getUserMemberFromID: [_dic objectForKey: _OPForum_LastPosterID] 
																withName: [_dic objectForKey: _OPForum_LastPosterName]] retain];
	
	// last post id
	[p_lastPostID release]; p_lastPostID = nil;
	p_lastPostID = [[NSNumber alloc] initWithInt: [[_dic objectForKey: _OPForum_LastPostID] intValue]];

	// update new topics since login
	[p_newTopicsSinceLogin release]; p_newTopicsSinceLogin = nil;
	p_newTopicsSinceLogin = [[NSNumber alloc] initWithInt:  [[_dic objectForKey: @"forum_newtopics_sincedate"] intValue]];
	
	// update updated topics since login
	[p_updatedTopicsSinceLogin release]; p_updatedTopicsSinceLogin = nil;
	p_updatedTopicsSinceLogin = [[NSNumber alloc] initWithInt:  [[_dic objectForKey: @"forum_updatedtopics_sincedate"] intValue]];
	
	// topics elements
	
	_forumPages.p_totalElements = [[_dic objectForKey: @"count_topics"] intValue];
	_forumPages.p_totalPages = ceil(_forumPages.p_totalElements / [[_delegateBoard.obj_boardConfig getPropertyForKey: OPBoardConfig_TopicsPerPage] intValue]);
}


- (NSArray *) getTopicsAtPage:(NSNumber *) _pgIdx {
	if ([_forumPages getPageAtIndex: _pgIdx] == nil || [self isCacheExpired] || _forumPages.p_totalElements == 0) { // if we want to get a new copy or we have not yet downloaded the page or the cache is expired
		[self sendXMLRequestForMethod: @"msgs.getTopicsFromForum" 
						   withParams: [NSArray arrayWithObjects: 
											[NSNumber numberWithInt: _forumID],
											_pgIdx,
											[_delegateBoard.obj_boardConfig getPropertyForKey: OPBoardConfig_TopicsPerPage],
											[_delegateBoard.obj_boardConfig getPropertyForKey: OPBoardConfig_PostsPerPage],
											_forumPassword,
											@"",
											[NSNumber numberWithInt: [_delegateBoard.obj_authUser.user_loginDate timeIntervalSince1970]], nil]
						parseSelector: @selector(_parseLoadTopicsAtPageRequest:)];
	} else [self dataUpdatedFor: self atMethod:@"msgs.getTopicsFromForum"];
	
	return [_forumPages getPageAtIndex: _pgIdx]; // return the results (only in sync mode, otherwise it will return nil)
	
}

// async response
- (void)connection: (XMLRPCConnection *)connection didReceiveResponse:(XMLRPCResponse *)response forMethod: (NSString *)method {	
	// super class check if it's an error, a numeric response or simply some data to parse
	if (![self _checkErrorInRawResponseFromServer: response forMethod:method]) {
		if ([method isEqualToString:@"msgs.getForumInfo"])
			[self _parseRefreshForumProperties: [NSArray arrayWithObjects: [response responseObject],method,nil]];
		else 
			// data update to parse
			[self _parseLoadTopicsAtPageRequest: [NSArray arrayWithObjects: [response responseObject],method,nil]];		
		// we can propagate the result to listeners
		[self dataUpdatedFor: self atMethod:method];	
	}
}

- (void) _parseLoadTopicsAtPageRequest:(NSArray *) _results {
	NSDictionary *prop = [(NSDictionary*)[_results objectAtIndex:0] retain];
		
	// what page we have received?
	int pageShowed = [[[prop objectForKey: _OPForum_ForumInfo] objectForKey: _OPForum_ForumInfo_PageShowed] intValue];
	// update some cached information about the topic
	_forumPages.p_totalElements = [[[prop objectForKey: _OPForum_ForumInfo] objectForKey: _OPForum_ForumInfo_TotalTopics] intValue];
	_forumPages.p_totalPages = [[[prop objectForKey: _OPForum_ForumInfo] objectForKey: _OPForum_ForumInfo_TotalPages] intValue];
	
	// update new topics since login
	[p_newTopicsSinceLogin release];
	p_newTopicsSinceLogin = [[[prop objectForKey: _OPForum_ForumInfo] objectForKey: @"forum_newtopics_sincedate"] retain];
	
	// update updated topics since login
	[p_updatedTopicsSinceLogin release];
	p_updatedTopicsSinceLogin = [[[prop objectForKey: _OPForum_ForumInfo] objectForKey: @"forum_updatedtopics_sincedate"] retain];
	
	// load the page items		
	NSMutableArray *topicsList = [[NSMutableArray alloc] init];
		
	for (NSDictionary *cTopic in [prop objectForKey: _OPForum_Topics]) {
		OPTopic *topic = [[[OPTopic alloc] _initWithDataResponse: cTopic ofForum: self] autorelease];
		[topicsList addObject: topic];
	}
				
	// assign to page
	[_forumPages addPage: [topicsList autorelease] atIndex:[NSNumber numberWithInt: pageShowed]];
	[prop release];
}

- (BOOL) _isNumericResponseFromServerAnErrorCode:(NSNumber *) _code forMethod:(NSString *) method {
	//switch ([_code intValue]) {
			
	//}
	return NO;
}

- (OPTopic *) getCachedTopicWithID:(NSNumber *) _id {
	NSArray *cachedTopics = [_forumPages getFlatElements];
	for (OPTopic *cTopic in cachedTopics)
		if ([cTopic.p_topicID intValue] == [_id intValue])
			return cTopic;
	return nil;
}

- (NSArray *) getModerators {
	XMLRPCResponse *dataMessage = [_delegateBoard _executeRequestMethodNamed: @"stats.getModsFromForumID" 
														withParams: [NSArray arrayWithObject: [NSNumber numberWithInt: _forumID]]
													attachAuthData: NO];
	NSMutableArray *list = [[NSMutableArray alloc] init];
	if (![dataMessage isFault]) {
		NSArray *users = [dataMessage responseObject];
		for (NSDictionary *cUser in users) {
			OPUser *_user = [_delegateBoard.obj_membersCache getUserMemberFromID: [cUser objectForKey: @"user_id"] withName: [cUser objectForKey: @"username"]];
			[list addObject: _user];
		}
		return [list autorelease];
	} else return nil;
}

- (void) refreshData {
	NSArray *params = [NSArray arrayWithObjects: [NSNumber numberWithInt: _forumID],
					   [NSNumber numberWithLongLong: [_delegateBoard.obj_authUser.user_loginDate timeIntervalSince1970]],nil];
	
	[self sendXMLRequestForMethod: @"msgs.getForumInfo" 
					   withParams: params
					parseSelector:  @selector(_parseRefreshForumProperties:)];
}

- (void) _parseRefreshForumProperties:(NSArray *) _result {
	[self _loadForumProperties: [_result objectAtIndex: 0]];
}

@end
